package com.sunsharing.flow.model;

import com.sunsharing.common.anno.AnoClassCretator;
import com.sunsharing.common.utils.IOUtils;
import com.sunsharing.common.utils.StringUtils;
import com.sunsharing.flow.event.ProcessInstanceCreateEvent;
import com.sunsharing.flow.event.ProcessInstanceEndEvent;
import com.sunsharing.flow.model.node.*;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;

import java.io.File;
import java.util.*;

/**
 * Created with IntelliJ IDEA.
 * User: criss
 * Date: 13-5-4
 * Time: 下午1:54
 * To change this template use File | Settings | File Templates.
 */
public class ProcessDefinition extends GraphElement {

    //id
    private String id;

    private String output;


    //开始节点
    private StartNode startNode = null;


    //所有的节点
    private List nodes = new ArrayList();

    //支持的事件类型
    public static final Class[] supportedEventTypes = new Class[] {
            ProcessInstanceCreateEvent.class,ProcessInstanceEndEvent.class
            //,
            //ProcessInstanceSuspendEvent.class,ProcessInstanceResumeEvent.class
    };




    /**
     * 功能描述:
     *     通过流程模版ID加载配置的流程定义
     * @param
     * @return ProcessDefinition
     */
    public static ProcessDefinition getProcessDefinition(String processDefId) {
        ProcessDefinition def = new ProcessDefinition();

        return def;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getId() {
        return this.id;
    }


    public List getNodes() {
        return nodes;
    }

    public void setNodes(List nodes) {
        this.nodes = nodes;
    }


     public Node getEndNode()
     {
          for(Iterator iter = nodes.iterator();iter.hasNext();)
          {
              Node next = (Node)iter.next();
              if(next instanceof EndNode)
              {
                  return next;
              }
          }
         throw new RuntimeException(this.id+"找不到结束节点");
     }

     public Node getNodeById(String noId)
     {
         for(Iterator iter = nodes.iterator();iter.hasNext();)
         {
             Node next = (Node)iter.next();
             if(next.getId().equals(noId))
             {
                 return next;
             }
         }
         throw new RuntimeException(this.id+"找不到节点"+noId);
     }





    /**
     * 功能描述:
     *     增加一个节点
     * @param node Node
     * @return Node
     */
    public Node addNode(Node node) {

        if (node == null) {
            throw new IllegalArgumentException(
                    "不能为流程过程定义增加一个空的节点!");
        }
        if (nodes == null) {
            nodes = new ArrayList();
        }
        nodes.add(node);


        if (node instanceof StartNode) {
            this.startNode = (StartNode)node;
        }

        return node;
    }


    public Node removeNode(Node node) {
        Node removedNode = null;
        if (node == null) {
            throw new IllegalArgumentException(
                    "can't remove a null node from a process definition");
        }
        if (nodes != null) {
            if (nodes.remove(node)) {
                removedNode = node;

            }
            node.processDefinition = null;
            node.removeAllArrivingTransitions();
            node.removeAllLeavingTransitions();
        }

        if (startNode == removedNode) {
            startNode = null;
        }


        return removedNode;
    }


    public static String generateNodeName(List nodes) {
        String name = null;
        if (nodes == null) {
            name = "1";
        } else {
            int n = 1;
            while (containsName(nodes, Integer.toString(n))) {
                n++;
            }
            name = Integer.toString(n);
        }
        return name;
    }

    static boolean containsName(List nodes, String name) {
        Iterator iter = nodes.iterator();
        while (iter.hasNext()) {
            Node node = (Node) iter.next();
            if (name.equals(node.getName())) {
                return true;
            }
        }
        return false;
    }




    public Node getStartNode() {
        return startNode;
    }

    public void setStartNode(StartNode startNode) {
        this.startNode = startNode;
    }





    public String getDesc() {
        return desc;
    }

    public String getName() {
        return name;
    }





    public void setDesc(String desc) {
        this.desc = desc;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Class[] getSupportedEventTypes() {
        return supportedEventTypes;
    }

    public String getOutput() {
        return output;
    }

    public void setOutput(String output) {
        this.output = output;
    }
}